package model.algorithms;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;

public abstract class AbsSearcher implements ISearcher {
	private PriorityQueue<State> openList;
	private ArrayList<State> closeList;
	private int evaluatedNodesNum;
	
	public AbsSearcher(Comparator<State> compOpenList) {
		setOpenList(new PriorityQueue<State>(1, compOpenList));
		setCloseList(new ArrayList<State>());

	}
	
	private void setOpenList(PriorityQueue<State> openList) {
		this.openList = openList;	
	}
	
	public PriorityQueue<State> getOpenList() {
		return openList;
	}
	
	public abstract ArrayList<IAction> search(State start, State goal);
	
	public int getEvaluatedNodesNum() {
		return evaluatedNodesNum;
	}

	public void setEvaluatedNodesNum(int evaluatedNodesNum) {
		this.evaluatedNodesNum = evaluatedNodesNum;
	}

	public ArrayList<State> getCloseList() {
		return closeList;
	}

	public void setCloseList(ArrayList<State> closeList) {
		this.closeList = closeList;
	}
	
//	public void addToOpenList(State state) {
//		if (!openList.contains(state)) {
//				openList.add(state);
//				this.evaluatedNodesNum++;
//		}	
//		else {
//				openList.remove(state);
//		}
//	}
//	
	public boolean addToOpenList(State state)
	{
		//If the state doesn't exist in openList - add it and inc the numOfNodes
		if ( openList.contains(state) == false )
		{
			boolean boolAdd = openList.add(state);
			if (boolAdd)
				this.evaluatedNodesNum++;
			return boolAdd;
		}
		//If exists remove and add the state into the openList
		else
		{
			boolean boolRemove = openList.remove(state);
			if (boolRemove)
				return openList.add(state);
			else
				return boolRemove;
		}
	}
	
	public State pollFromOpenList() {
		return this.openList.poll();
	}
	
	public boolean isEmptyOpenList() {
		return this.openList.isEmpty();
	}
	
	public boolean containsInOpenList(State state) {
		if (this.openList.contains(state)) {
			return true;
		}
		else {
			return false;
		}
	}

	public boolean addToCloseList(State state) {
		return this.closeList.add(state);
	}
	
	public boolean removeFromCloseList(State state) {
		return this.closeList.remove(state);
	}
	
	public boolean containsInCloseList(State state) {
		if (this.closeList.contains(state)) {
			return true;
		}
		else {
			return false;
		}
	}
}
